package org.springframework.learn.beans.note.determineConstructors;

import org.springframework.beans.factory.config.RuntimeBeanNameReference;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.learn.beans.service.OrderService;
import org.springframework.learn.beans.service.UserService;


@Configuration
//@ComponentScan(value = {"org.springframework.learn.beans.config","org.springframework.learn.beans.factory"})
//@ComponentScan(value = {"org.springframework.learn.beans.data", "org.springframework.learn.beans.aspect"})
@ComponentScan(value = {"org.springframework.learn.beans.service"})
@EnableAspectJAutoProxy
//@EnableAsync
public class BeanApplication {
	public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
		// 1、默认使用无参的构造函数，或者只有一个构造函数的情况下使用该构造函数
//		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanApplication.class);
//		OrderService orderService = (OrderService) context.getBean("orderService");

		// 2、懒加载+getBean可以指定构造函数
//		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanApplication.class);
//		OrderService orderService = (OrderService) context.getBean("orderService", new UserService());

		// 3、设置autowire="constructor"让Spring自动选择构造方法以及注入构造方法的入参值，spring会使用入参最多的构造方法。
//		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//		context.register(BeanApplication.class);
//		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
//		beanDefinition.setBeanClass(OrderService.class);
//		beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
//		context.registerBeanDefinition("orderService", beanDefinition);
//		context.refresh();
//		OrderService orderService = (OrderService) context.getBean("orderService", new UserService());

		// 4、通过BeanDefinition.getConstructorArgumentValues()指定构造方法。
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(BeanApplication.class);
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		beanDefinition.setBeanClass(OrderService.class);
		UserService u = new UserService();
		UserService u1 = new UserService();
		System.out.println(u);
		System.out.println(u1);
		beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(u);
		beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(u1);
//		beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(1, u1);
//		beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("userService"));
		context.registerBeanDefinition("orderService", beanDefinition);
		context.refresh();
		OrderService orderService = (OrderService) context.getBean("orderService");
//		OrderService orderService = (OrderService) context.getBean("orderService", new UserService());

	}
}
